#pragma once

#include <iostream>
#include <stdarg.h>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>


#include <ctime>

#define Info    0
#define Debug   1
#define Warning 2
#define Error   3
#define Fatal   4

#define Screen    1
#define Onefile   2
#define Classfile 3

#define SIZE 1024

#define Logfile "log.txt"

class Log
{
public:
    Log()
    {
        printMethod = Screen;
        path = "./log/";
    }

    void Enable(int method)
    {
        printMethod = method;
    }

    const char *leveToString(int level)
    {
        switch (level)
        {
        case Info:
            return "Info";
            break;
        case Debug:
            return "Dubug";
            break;
        case Warning:
            return "Warning";
            break;
        case Error:
            return "Error";
            break;
        case Fatal:
            return "Fatal";
            break;
        default:
            return "None";
            break;
        }
    }

    // void logmessage(int level, const char *format, ...)
    // {
    //     // std::cout << time(nullptr) << std::endl;

    //     time_t t = time(nullptr);
    //     struct tm *ctime = localtime(&t);

    //     char leftbuffer[SIZE];
    //     snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", leveToString(level), ctime->tm_year + 1900,
    //              ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

    //     // printf("%s\n",leftbuffer);

    //     char rightbuffer[SIZE];
    //     va_list s;
    //     va_start(s, format);
    //     // 按照我们指定的格式,格式化字符串
    //     vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
    //     // 格式: 默认部分+自定义部分
    //     char logtxt[2 * SIZE];
    //     snprintf(logtxt, sizeof(logtxt) + 2, "%s %s\n", leftbuffer, rightbuffer);
    //     va_end(s);

    //     //printf("%s\n", logtxt);
    //     PrintLog(level,logtxt);

    //     // printf("%d-%d-%d %d:%d:%d\n",ctime->tm_year + 1900,ctime->tm_mon + 1,ctime->tm_mday,ctime->tm_hour
    //     //,ctime->tm_min,ctime->tm_sec);
    // }

    void PrintLog(int level,const std::string& logtxt)
    {
        switch (printMethod)
        {
        case Screen:
            std::cout << logtxt << std::endl;
            break;
        case Onefile:
            printOnefile(Logfile,logtxt);
            break;
        case Classfile:
            printClassfile(level,logtxt);
            break;
        
        default:
            break;
        }
    }
    void printOnefile(const std::string& logname, const std::string& logtxt)
    {
        std::string LogName = path + logname;
        int fd = open(LogName.c_str(),O_WRONLY|O_CREAT|O_APPEND,0666);
        if (fd < 0)
        {
            return;
        }

        write(fd,logtxt.c_str(),logtxt.size());
        close(fd);
    }


    void printClassfile(int level,const std::string& logtxt)
    {
        std::string filename = Logfile;
        filename += ".";
        filename += leveToString(level);

        printOnefile(filename,logtxt);
    }


    void operator()(int level,const char* format,...)
    {
        time_t t = time(nullptr);
        struct tm *ctime = localtime(&t);

        char leftbuffer[SIZE];
        snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", leveToString(level), ctime->tm_year + 1900,
                 ctime->tm_mon + 1, ctime->tm_mday, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);

        // printf("%s\n",leftbuffer);

        char rightbuffer[SIZE];
        va_list s;
        va_start(s, format);
        // 按照我们指定的格式,格式化字符串
        vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
        // 格式: 默认部分+自定义部分
        char logtxt[2 * SIZE];
        snprintf(logtxt, sizeof(logtxt) + 2, "%s %s\n", leftbuffer, rightbuffer);
        va_end(s);

        //printf("%s\n", logtxt);
        PrintLog(level,logtxt);
    }


    ~Log()
    {

    }
private:
    int printMethod;
    std::string path;
};

// int sum(int n,...)
// {
//     va_list s; //char* 找起始地址
//     va_start(s,n);

//     int sum = 0;
//     while(n)
//     {
//         sum += va_arg(s,int);
//         n--;
//     }

//     va_end(s); // s = NULL

//     return sum;
// }